#include "map_process/image_saver.h"
#include <filesystem>
#include <algorithm>
#include <iostream>

namespace map_process
{

// 构造函数：初始化支持的图像扩展名列表
ImageSaver::ImageSaver()
{
    // 初始化支持的图像文件扩展名
    initializeSupportedExtensions();
}

// 析构函数：清理资源
ImageSaver::~ImageSaver()
{
    // 当前无需清理操作
}

// 初始化支持的图像扩展名列表
void ImageSaver::initializeSupportedExtensions()
{
    // 设置支持的图像格式：PNG、JPEG、BMP、TIFF
    supported_extensions_ = {".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".tif"};
}

// 保存图像到指定路径
bool ImageSaver::saveImage(const cv::Mat& image, const std::string& file_path)
{
    // ========== 步骤1：验证图像有效性 ==========
    // 检查图像是否为空
    if (image.empty()) {
        std::cerr << "错误：无法保存空图像" << std::endl;
        return false;
    }

    // ========== 步骤2：检查文件格式 ==========
    // 检查文件扩展名是否在支持的图像格式列表中
    if (!isSupportedFormat(file_path)) {
        std::cerr << "错误：不支持的图像格式 " << file_path << std::endl;
        std::cerr << "支持的格式：.png, .jpg, .jpeg, .bmp, .tiff, .tif" << std::endl;
        return false;
    }

    // ========== 步骤3：创建目录（如果不存在） ==========
    // 提取文件路径的目录部分
    std::filesystem::path path_obj(file_path);
    std::filesystem::path directory = path_obj.parent_path();
    
    // 如果目录不为空且不存在，则创建目录
    if (!directory.empty() && !std::filesystem::exists(directory)) {
        try {
            std::filesystem::create_directories(directory);
        } catch (const std::filesystem::filesystem_error& e) {
            std::cerr << "错误：无法创建目录 " << directory << ": " << e.what() << std::endl;
            return false;
        }
    }

    // ========== 步骤4：使用OpenCV保存图像 ==========
    // 使用 OpenCV 的 imwrite 函数保存图像
    // imwrite 会根据文件扩展名自动选择相应的编码器
    bool success = cv::imwrite(file_path, image);

    // ========== 步骤5：验证保存结果 ==========
    // 检查图像是否成功保存
    if (!success) {
        std::cerr << "错误：无法保存图像到 " << file_path << std::endl;
        return false;
    }

    return true;
}

// 检查文件扩展名是否为支持的图像格式
bool ImageSaver::isSupportedFormat(const std::string& file_path)
{
    // ========== 步骤1：提取文件扩展名 ==========
    // 从文件路径中提取扩展名（包括点号，如 ".png"）
    std::string extension = std::filesystem::path(file_path).extension().string();
    
    // ========== 步骤2：转换为小写 ==========
    // 将扩展名转换为小写，实现大小写不敏感的匹配
    std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);

    // ========== 步骤3：检查是否在支持列表中 ==========
    // 在支持的扩展名列表中查找匹配项
    return std::find(supported_extensions_.begin(), supported_extensions_.end(), extension) != supported_extensions_.end();
}

}  // namespace map_process

